/**
 * $Id: Toolbar.js,v 1.4 2013/05/01 13:10:22 gaudenz Exp $
 * Copyright (c) 2006-2012, JGraph Ltd
 */
/**
 * Construcs a new toolbar for the given editor.
 */
function Toolbar(editorUi, container)
{
    this.editorUi = editorUi;
    this.container = container;
    this.init();

    // Global handler to hide the current menu
    mxEvent.addGestureListeners(document, mxUtils.bind(this, function(evt)
    {
        this.hideMenu();
    }));
}
;

/**
 * Adds the toolbar elements.
 */
Toolbar.prototype.init = function()
{
    this.addItems(['undo', 'redo', 'delete', '-', 'actualSize', 'zoomIn', 'zoomOut', '-']);
    var fontElt = this.addMenu('Helvetica', mxResources.get('fontFamily'), true, 'fontFamily');
    fontElt.style.whiteSpace = 'nowrap';
    fontElt.style.overflow = 'hidden';
    fontElt.style.width = '56px';
    this.addSeparator();
    var sizeElt = this.addMenu('12', mxResources.get('fontSize'), true, 'fontSize');
    sizeElt.style.whiteSpace = 'nowrap';
    sizeElt.style.overflow = 'hidden';
    sizeElt.style.width = '22px';

    this.addItems(['-', 'bold', 'italic', 'underline']);
    var align = this.addMenuFunction('geSprite-left', mxResources.get('align'), false, mxUtils.bind(this, function(menu)
    {
        this.editorUi.menus.styleChange(menu, '', [mxConstants.STYLE_ALIGN], [mxConstants.ALIGN_LEFT], 'geIcon geSprite geSprite-left', null).setAttribute('title', mxResources.get('left'));
        this.editorUi.menus.styleChange(menu, '', [mxConstants.STYLE_ALIGN], [mxConstants.ALIGN_CENTER], 'geIcon geSprite geSprite-center', null).setAttribute('title', mxResources.get('center'));
        this.editorUi.menus.styleChange(menu, '', [mxConstants.STYLE_ALIGN], [mxConstants.ALIGN_RIGHT], 'geIcon geSprite geSprite-right', null).setAttribute('title', mxResources.get('right'));
        this.editorUi.menus.styleChange(menu, '', [mxConstants.STYLE_VERTICAL_ALIGN], [mxConstants.ALIGN_TOP], 'geIcon geSprite geSprite-top', null).setAttribute('title', mxResources.get('top'));
        this.editorUi.menus.styleChange(menu, '', [mxConstants.STYLE_VERTICAL_ALIGN], [mxConstants.ALIGN_MIDDLE], 'geIcon geSprite geSprite-middle', null).setAttribute('title', mxResources.get('middle'));
        this.editorUi.menus.styleChange(menu, '', [mxConstants.STYLE_VERTICAL_ALIGN], [mxConstants.ALIGN_BOTTOM], 'geIcon geSprite geSprite-bottom', null).setAttribute('title', mxResources.get('bottom'));
    }));
    this.addItems(['fontColor', '-']);
    var line = this.addMenuFunction('geSprite-straight', mxResources.get('line'), false, mxUtils.bind(this, function(menu)
    {
        this.editorUi.menus.styleChange(menu, '', [mxConstants.STYLE_EDGE], [null], 'geIcon geSprite geSprite-straight', null).setAttribute('title', mxResources.get('straight'));
        this.editorUi.menus.styleChange(menu, '', [mxConstants.STYLE_EDGE], ['entityRelationEdgeStyle'], 'geIcon geSprite geSprite-entity', null).setAttribute('title', mxResources.get('entityRelation'));
        this.editorUi.menus.styleChange(menu, '', [mxConstants.STYLE_EDGE, mxConstants.STYLE_ELBOW], ['elbowEdgeStyle', 'horizontal'], 'geIcon geSprite geSprite-helbow', null).setAttribute('title', mxResources.get('horizontal'));
        this.editorUi.menus.styleChange(menu, '', [mxConstants.STYLE_EDGE, mxConstants.STYLE_ELBOW], ['elbowEdgeStyle', 'vertical'], 'geIcon geSprite geSprite-velbow', null).setAttribute('title', mxResources.get('vertical'));
        this.editorUi.menus.styleChange(menu, '', [mxConstants.STYLE_EDGE], ['segmentEdgeStyle'], 'geIcon geSprite geSprite-segment', null).setAttribute('title', mxResources.get('manual'));
        this.editorUi.menus.styleChange(menu, '', [mxConstants.STYLE_EDGE], ['orthogonalEdgeStyle'], 'geIcon geSprite geSprite-orthogonal', null).setAttribute('title', mxResources.get('automatic'));
    }));
    var linestart = this.addMenuFunction('geSprite-startclassic', mxResources.get('lineend'), false, mxUtils.bind(this, function(menu)
    {
        this.editorUi.menus.styleChange(menu, '', [mxConstants.STYLE_STARTARROW, 'startFill'], [mxConstants.NONE, 0], 'geIcon geSprite geSprite-noarrow', null).setAttribute('title', mxResources.get('none'));
        this.editorUi.menus.styleChange(menu, '', [mxConstants.STYLE_STARTARROW, 'startFill'], [mxConstants.ARROW_CLASSIC, 1], 'geIcon geSprite geSprite-startclassic', null).setAttribute('title', mxResources.get('classic'));
        this.editorUi.menus.styleChange(menu, '', [mxConstants.STYLE_STARTARROW, 'startFill'], [mxConstants.ARROW_OPEN, 1], 'geIcon geSprite geSprite-startopen', null).setAttribute('title', mxResources.get('openArrow'));
        this.editorUi.menus.styleChange(menu, '', [mxConstants.STYLE_STARTARROW, 'startFill'], [mxConstants.ARROW_BLOCK, 1], 'geIcon geSprite geSprite-startblock', null).setAttribute('title', mxResources.get('block'));
        this.editorUi.menus.styleChange(menu, '', [mxConstants.STYLE_STARTARROW, 'startFill'], [mxConstants.ARROW_OVAL, 1], 'geIcon geSprite geSprite-startoval', null).setAttribute('title', mxResources.get('oval'));
        this.editorUi.menus.styleChange(menu, '', [mxConstants.STYLE_STARTARROW, 'startFill'], [mxConstants.ARROW_DIAMOND, 1], 'geIcon geSprite geSprite-startdiamond', null).setAttribute('title', mxResources.get('diamond'));
        this.editorUi.menus.styleChange(menu, '', [mxConstants.STYLE_STARTARROW, 'startFill'], [mxConstants.ARROW_DIAMOND_THIN, 1], 'geIcon geSprite geSprite-startthindiamond', null).setAttribute('title', mxResources.get('diamondThin'));
        this.editorUi.menus.styleChange(menu, '', [mxConstants.STYLE_STARTARROW, 'startFill'], [mxConstants.ARROW_CLASSIC, 0], 'geIcon geSprite geSprite-startclassictrans', null).setAttribute('title', mxResources.get('classic'));
        this.editorUi.menus.styleChange(menu, '', [mxConstants.STYLE_STARTARROW, 'startFill'], [mxConstants.ARROW_BLOCK, 0], 'geIcon geSprite geSprite-startblocktrans', null).setAttribute('title', mxResources.get('block'));
        this.editorUi.menus.styleChange(menu, '', [mxConstants.STYLE_STARTARROW, 'startFill'], [mxConstants.ARROW_OVAL, 0], 'geIcon geSprite geSprite-startovaltrans', null).setAttribute('title', mxResources.get('oval'));
        this.editorUi.menus.styleChange(menu, '', [mxConstants.STYLE_STARTARROW, 'startFill'], [mxConstants.ARROW_DIAMOND, 0], 'geIcon geSprite geSprite-startdiamondtrans', null).setAttribute('title', mxResources.get('diamond'));
        this.editorUi.menus.styleChange(menu, '', [mxConstants.STYLE_STARTARROW, 'startFill'], [mxConstants.ARROW_DIAMOND_THIN, 0], 'geIcon geSprite geSprite-startthindiamondtrans', null).setAttribute('title', mxResources.get('diamondThin'));
    }));
    var lineend = this.addMenuFunction('geSprite-endclassic', mxResources.get('lineend'), false, mxUtils.bind(this, function(menu)
    {
        this.editorUi.menus.styleChange(menu, '', [mxConstants.STYLE_ENDARROW, 'endFill'], [mxConstants.NONE, 0], 'geIcon geSprite geSprite-noarrow', null).setAttribute('title', mxResources.get('none'));
        this.editorUi.menus.styleChange(menu, '', [mxConstants.STYLE_ENDARROW, 'endFill'], [mxConstants.ARROW_CLASSIC, 1], 'geIcon geSprite geSprite-endclassic', null).setAttribute('title', mxResources.get('classic'));
        this.editorUi.menus.styleChange(menu, '', [mxConstants.STYLE_ENDARROW, 'endFill'], [mxConstants.ARROW_OPEN, 1], 'geIcon geSprite geSprite-endopen', null).setAttribute('title', mxResources.get('openArrow'));
        this.editorUi.menus.styleChange(menu, '', [mxConstants.STYLE_ENDARROW, 'endFill'], [mxConstants.ARROW_BLOCK, 1], 'geIcon geSprite geSprite-endblock', null).setAttribute('title', mxResources.get('block'));
        this.editorUi.menus.styleChange(menu, '', [mxConstants.STYLE_ENDARROW, 'endFill'], [mxConstants.ARROW_OVAL, 1], 'geIcon geSprite geSprite-endoval', null).setAttribute('title', mxResources.get('oval'));
        this.editorUi.menus.styleChange(menu, '', [mxConstants.STYLE_ENDARROW, 'endFill'], [mxConstants.ARROW_DIAMOND, 1], 'geIcon geSprite geSprite-enddiamond', null).setAttribute('title', mxResources.get('diamond'));
        this.editorUi.menus.styleChange(menu, '', [mxConstants.STYLE_ENDARROW, 'endFill'], [mxConstants.ARROW_DIAMOND_THIN, 1], 'geIcon geSprite geSprite-endthindiamond', null).setAttribute('title', mxResources.get('diamondThin'));
        this.editorUi.menus.styleChange(menu, '', [mxConstants.STYLE_ENDARROW, 'endFill'], [mxConstants.ARROW_CLASSIC, 0], 'geIcon geSprite geSprite-endclassictrans', null).setAttribute('title', mxResources.get('classic'));
        this.editorUi.menus.styleChange(menu, '', [mxConstants.STYLE_ENDARROW, 'endFill'], [mxConstants.ARROW_BLOCK, 0], 'geIcon geSprite geSprite-endblocktrans', null).setAttribute('title', mxResources.get('block'));
        this.editorUi.menus.styleChange(menu, '', [mxConstants.STYLE_ENDARROW, 'endFill'], [mxConstants.ARROW_OVAL, 0], 'geIcon geSprite geSprite-endovaltrans', null).setAttribute('title', mxResources.get('oval'));
        this.editorUi.menus.styleChange(menu, '', [mxConstants.STYLE_ENDARROW, 'endFill'], [mxConstants.ARROW_DIAMOND, 0], 'geIcon geSprite geSprite-enddiamondtrans', null).setAttribute('title', mxResources.get('diamond'));
        this.editorUi.menus.styleChange(menu, '', [mxConstants.STYLE_ENDARROW, 'endFill'], [mxConstants.ARROW_DIAMOND_THIN, 0], 'geIcon geSprite geSprite-endthindiamondtrans', null).setAttribute('title', mxResources.get('diamondThin'));
    }));
    this.addItems(['-', 'strokeColor', 'image', 'fillColor']);
    this.addItem('geSprite-gradientcolor', 'gradientColor').setAttribute('title', mxResources.get('gradient'));
    this.addItems(['shadow']);

    var graph = this.editorUi.editor.graph;

    // Update font size and font family labels
    var update = mxUtils.bind(this, function()
    {
        var ff = 'Helvetica';
        var fs = '12';
        var state = graph.getView().getState(graph.getSelectionCell());

        if (state != null)
        {
            ff = state.style[mxConstants.STYLE_FONTFAMILY] || ff;
            fs = state.style[mxConstants.STYLE_FONTSIZE] || fs;

            if (ff.length > 10)
            {
                ff = ff.substring(0, 8) + '...';
            }

            fontElt.innerHTML = ff;
            sizeElt.innerHTML = fs;
        }
    });

    graph.getSelectionModel().addListener(mxEvent.CHANGE, update);
    graph.getModel().addListener(mxEvent.CHANGE, update);



   



    // Updates button states
    this.addEdgeSelectionHandler([line, linestart, lineend]);
    this.addSelectionHandler([align]);
};

/**
 * Hides the current menu.
 */
Toolbar.prototype.hideMenu = function()
{
    if (this.currentMenu != null)
    {
        this.currentMenu.hideMenu();
        this.currentMenu.destroy();
        this.currentMenu = null;
    }
};

/**
 * Adds a label to the toolbar.
 */
Toolbar.prototype.addMenu = function(label, tooltip, showLabels, name)
{
    var menu = this.editorUi.menus.get(name);
    var elt = this.addMenuFunction(label, tooltip, showLabels, menu.funct);

    menu.addListener('stateChanged', function()
    {
        elt.setEnabled(menu.enabled);
    });

    return elt;
};

/**
 * Adds a label to the toolbar.
 */
Toolbar.prototype.addMenuFunction = function(label, tooltip, showLabels, funct)
{
    var elt = (showLabels) ? this.createLabel(label) : this.createButton(label);
    this.initElement(elt, tooltip);
    this.addMenuHandler(elt, showLabels, funct);
    this.container.appendChild(elt);

    return elt;
};

/**
 * Adds a separator to the separator.
 */
Toolbar.prototype.addSeparator = function()
{
    var elt = document.createElement('div');
    elt.className = 'geSeparator';
    this.container.appendChild(elt);

    return elt;
};

/**
 * Adds given action item
 */
Toolbar.prototype.addItems = function(keys)
{
    for (var i = 0; i < keys.length; i++)
    {
        var key = keys[i];

        if (key == '-')
        {
            this.addSeparator();
        }
        else
        {
            this.addItem('geSprite-' + key.toLowerCase(), key);
        }
    }
};

/**
 * Adds given action item
 */
Toolbar.prototype.addItem = function(sprite, key)
{
    var action = this.editorUi.actions.get(key);
    var elt = null;

    if (action != null)
    {
        elt = this.addButton(sprite, action.label, action.funct);
        elt.setEnabled(action.enabled);

        action.addListener('stateChanged', function()
        {
            elt.setEnabled(action.enabled);
        });
    }

    return elt;
};

/**
 * Adds a button to the toolbar.
 */
Toolbar.prototype.addButton = function(classname, tooltip, funct)
{
    var elt = this.createButton(classname);

    this.initElement(elt, tooltip);
    this.addClickHandler(elt, funct);
    this.container.appendChild(elt);

    return elt;
};

/**
 * Updates the states of the given toolbar items based on the selection.
 */
Toolbar.prototype.addSelectionHandler = function(items)
{
    var graph = this.editorUi.editor.graph;

    var selectionListener = function()
    {
        var selected = !graph.isSelectionEmpty();

        for (var i = 0; i < items.length; i++)
        {
            items[i].setEnabled(selected);
        }
    };

    graph.getSelectionModel().addListener(mxEvent.CHANGE, selectionListener);
    selectionListener();
};

/**
 * Updates the states of the given toolbar items based on the selection.
 */
Toolbar.prototype.addEdgeSelectionHandler = function(items)
{
    var graph = this.editorUi.editor.graph;

    var selectionListener = function()
    {
        var edgeSelected = false;

        if (!graph.isSelectionEmpty())
        {
            var cells = graph.getSelectionCells();

            for (var i = 0; i < cells.length; i++)
            {
                if (graph.getModel().isEdge(cells[i]))
                {
                    edgeSelected = true;
                    break;
                }
            }
        }

        for (var i = 0; i < items.length; i++)
        {
            items[i].setEnabled(edgeSelected);
        }
    };

    graph.getSelectionModel().addListener(mxEvent.CHANGE, selectionListener);
    selectionListener();
};

/**
 * Initializes the given toolbar element.
 */
Toolbar.prototype.initElement = function(elt, tooltip)
{
    elt.setAttribute('tabindex', '0');

    // Adds tooltip
    if (tooltip != null)
    {
        elt.setAttribute('title', tooltip);
    }

    this.addEnabledState(elt);
};

/**
 * Adds enabled state with setter to DOM node (avoids JS wrapper).
 */
Toolbar.prototype.addEnabledState = function(elt)
{
    var classname = elt.className;

    elt.setEnabled = function(value)
    {
        elt.enabled = value;

        if (value)
        {
            elt.className = classname;
        }
        else
        {
            elt.className = classname + ' geDisabled';
        }
    };

    elt.setEnabled(true);
};

/**
 * Adds enabled state with setter to DOM node (avoids JS wrapper).
 */
Toolbar.prototype.addClickHandler = function(elt, funct)
{
    if (funct != null)
    {
        mxEvent.addListener(elt, 'click', function(evt)
        {
            if (elt.enabled)
            {
                funct(evt);
            }

            mxEvent.consume(evt);
        });
    }
};

/**
 * Creates and returns a new button.
 */
Toolbar.prototype.createButton = function(classname)
{
    var elt = document.createElement('a');
    elt.setAttribute('href', 'javascript:void(0);');
    elt.className = 'geButton';

    var inner = document.createElement('div');
    inner.className = 'geSprite ' + classname;
    elt.appendChild(inner);

    return elt;
};

/**
 * Creates and returns a new button.
 */
Toolbar.prototype.createLabel = function(label, tooltip)
{
    var elt = document.createElement('a');
    elt.setAttribute('href', 'javascript:void(0);');
    elt.className = 'geLabel';
    mxUtils.write(elt, label);

    return elt;
};

/**
 * Adds a handler for showing a menu in the given element.
 */
Toolbar.prototype.addMenuHandler = function(elt, showLabels, funct, showAll)
{
    if (funct != null)
    {
        var graph = this.editorUi.editor.graph;
        var menu = null;

        mxEvent.addListener(elt, 'click', mxUtils.bind(this, function(evt)
        {
            if (elt.enabled == null || elt.enabled)
            {
                graph.panningHandler.hideMenu();
                menu = new mxPopupMenu(funct);
                menu.div.className += ' geToolbarMenu';
                menu.showDisabled = showAll;
                menu.labels = showLabels;
                menu.autoExpand = true;

                menu.popup(elt.offsetLeft, elt.offsetTop + elt.offsetHeight + 34, null, evt);
                this.currentMenu = menu;
            }

            mxEvent.consume(evt);
        }));
    }
};
